package com.watson.tool.utils;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

/**
 * 加/解密工具类
 */
public class CryptUtils {

	/**
	 * DES加密类型
	 */
	public static final String CRYPTO_DES = "DES";

	/**
	 * AES加密类型
	 */
	public static final String CRYPTO_AES = "AES";

	/**
	 * Key 8位以上
	 */
	private static final String SECRET_KEY = "Spiccpiinfo@1821";

	/**
	 * IV 8位以上
	 */
	private static final String SECRET_IV = "IotPlatform@1821";

	/**
	 * AES
	 */
	private static final String CIPHER_KEY = "AES/CBC/PKCS5Padding";

	/**
	 * DES 加密
	 * 
	 * @param param
	 * @return
	 * @throws Exception
	 */
	public static final String encryptDES(String param) {
		try {
			Cipher cipher = Cipher.getInstance(CRYPTO_DES);
			SecretKeyFactory des = SecretKeyFactory.getInstance(CRYPTO_DES);
			SecretKey secretKey = des.generateSecret(new DESKeySpec(SECRET_KEY.getBytes()));
			cipher.init(Cipher.ENCRYPT_MODE, secretKey);
			return new String(Base64.getEncoder().encode(cipher.doFinal(param.toString().getBytes())), "utf-8");
		}catch(Exception ex) {
			throw new RuntimeException("exception while encryptDES.", ex);
		}
	}

	/**
	 * DES 解密
	 * 
	 * @param value
	 * @return
	 * @throws Exception
	 */
	public static final String decryptDES(String value){
		try {
			Cipher cipher = Cipher.getInstance(CRYPTO_DES);
			SecretKeyFactory des = SecretKeyFactory.getInstance(CRYPTO_DES);
			SecretKey secretKey = des.generateSecret(new DESKeySpec(SECRET_KEY.getBytes()));
			cipher.init(Cipher.DECRYPT_MODE, secretKey);
			return new String(cipher.doFinal(Base64.getDecoder().decode(value.getBytes("utf-8"))));
		}catch(Exception ex) {
			throw new RuntimeException("exception while decryptDES.", ex);
		}
	}

	/**
	 * AES 加密
	 * 
	 * @param param
	 * @return
	 * @throws Exception
	 */
	public static String encryptAES(String param){
		try {
			Cipher cipher = Cipher.getInstance(CIPHER_KEY);
			SecretKeySpec skeySpec = new SecretKeySpec(SECRET_KEY.getBytes(), CRYPTO_AES);
			// 使用CBC模式，需要一个向量iv，可增加加密算法的强度
			IvParameterSpec iv = new IvParameterSpec(SECRET_IV.getBytes());
			cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
			return new String(Base64.getEncoder().encode(cipher.doFinal(param.getBytes("utf-8"))), "utf-8");
		}catch(Exception ex) {
			throw new RuntimeException("exception while encryptAES.", ex);
		}
	}

	/**
	 * AES 解密
	 * 
	 * @param value
	 * @return
	 * @throws Exception
	 */
	public static String decryptAES(String value) {
		try {
			SecretKeySpec skeySpec = new SecretKeySpec(SECRET_KEY.getBytes("utf-8"), CRYPTO_AES);
			Cipher cipher = Cipher.getInstance(CIPHER_KEY);
			IvParameterSpec iv = new IvParameterSpec(SECRET_IV.getBytes());
			cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
			return new String(cipher.doFinal(Base64.getDecoder().decode(value.getBytes("utf-8"))), "utf-8");
		}catch(Exception ex) {
			throw new RuntimeException("exception while decryptAES.", ex);
		}
	}
	
	public static void main(String[] args) {
		String key = "teststring@*#$9048203";
		String des = encryptDES(key);
		System.out.println(key + "---" + des + "---" + decryptDES(des));
		
		String aes = encryptAES(key);
		System.out.println(key + "---" + aes + "---" + decryptAES(aes));
	}
}
